home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / mail / pine3.96.tar.gz / pine3.96.tar / pine3.96 / pine / ttyout.c < prev   
C/C++ Source or Header  |  1996-07-10  |  55KB  |  2,145 lines

  1. #if !defined(lint) && !defined(DOS)
  2. static char rcsid[] = "$Id: ttyout.c,v 4.80 1996/07/11 01:45:32 mikes Exp $";
  3. #endif
  4. /*----------------------------------------------------------------------
  5.  
  6.             T H E    P I N E    M A I L   S Y S T E M
  7.  
  8.    Laurence Lundblade and Mike Seibel
  9.    Networks and Distributed Computing
  10.    Computing and Communications
  11.    University of Washington
  12.    Administration Builiding, AG-44
  13.    Seattle, Washington, 98195, USA
  14.    Internet: lgl@CAC.Washington.EDU
  15.              mikes@CAC.Washington.EDU
  16.  
  17.    Please address all bugs and comments to "pine-bugs@cac.washington.edu"
  18.  
  19.  
  20.    Pine and Pico are registered trademarks of the University of Washington.
  21.    No commercial use of these trademarks may be made without prior written
  22.    permission of the University of Washington.
  23.  
  24.    Pine, Pico, and Pilot software and its included text are Copyright
  25.    1989-1996 by the University of Washington.
  26.  
  27.    The full text of our legal notices is contained in the file called
  28.    CPYRIGHT, included with this distribution.
  29.  
  30.  
  31.    Pine is in part based on The Elm Mail System:
  32.     ***********************************************************************
  33.     *  The Elm Mail System  -  Revision: 2.13                             *
  34.     *                                                                     *
  35.     *             Copyright (c) 1986, 1987 Dave Taylor              *
  36.     *             Copyright (c) 1988, 1989 USENET Community Trust   *
  37.     ***********************************************************************
  38.  
  39.  
  40.   ----------------------------------------------------------------------*/
  41.  
  42. /*======================================================================
  43.        ttyout.c
  44.        Routines for painting the screen
  45.           - figure out what the terminal type is
  46.           - deal with screen size changes
  47.           - save special output sequences
  48.           - the usual screen clearing, cursor addressing and scrolling
  49.  
  50.  
  51.      This library gives programs the ability to easily access the
  52.      termcap information and write screen oriented and raw input
  53.      programs.  The routines can be called as needed, except that
  54.      to use the cursor / screen routines there must be a call to
  55.      InitScreen() first.  The 'Raw' input routine can be used
  56.      independently, however. (Elm comment)
  57.  
  58.      Not sure what the original source of this code was. It got to be
  59.      here as part of ELM. It has been changed significantly from the
  60.      ELM version to be more robust in the face of inconsistent terminal
  61.      autowrap behaviour. Also, the unused functions were removed, it was
  62.      made to pay attention to the window size, and some code was made nicer
  63.      (in my opinion anyways). It also outputs the terminal initialization
  64.      strings and provides for minimal scrolling and detects terminals
  65.      with out enough capabilities. (Pine comment, 1990)
  66.  
  67.  
  68. This code used to pay attention to the "am" auto margin and "xn"
  69. new line glitch fields, but they were so often incorrect because many
  70. terminals can be configured to do either that we've taken it out. It
  71. now assumes it dosn't know where the cursor is after outputing in the
  72. 80th column.
  73. */
  74.  
  75. #ifdef OS2
  76. #define INCL_BASE
  77. #define INCL_VIO
  78. #define INCL_DOS
  79. #define INCL_NOPM
  80. #include <os2.h>
  81. #undef ADDRESS
  82. #endif
  83.  
  84. #include "headers.h"
  85.  
  86. #define FARAWAY 1000
  87. #define    PUTLINE_BUFLEN    256
  88.  
  89. static int   _lines, _columns;
  90. static int   _line  = FARAWAY;
  91. static int   _col   = FARAWAY;
  92. static int   _in_inverse;
  93.  
  94.  
  95. #if    !(defined(DOS) ||defined(OS2))
  96. /* Beginning of giant ifdef to switch between UNIX and DOS */
  97.  
  98. #ifdef _
  99. #include <sys/tty.h>
  100. #endif
  101.  
  102.  
  103. /*
  104.  * Internal prototypes
  105.  */
  106. static void moveabsolute PROTO((int, int));
  107. static void CursorUp PROTO((int));
  108. static void CursorDown PROTO((int));
  109. static void CursorLeft PROTO((int));
  110. static void CursorRight PROTO((int));
  111.  
  112.  
  113. static char *_clearscreen, *_moveto, *_up, *_down, *_right, *_left,
  114.             *_setinverse, *_clearinverse,
  115.             *_setunderline, *_clearunderline,
  116.             *_setbold,     *_clearbold,
  117.             *_cleartoeoln, *_cleartoeos,
  118.             *_startinsert, *_endinsert, *_insertchar, *_deletechar,
  119.             *_deleteline, *_insertline,
  120.             *_scrollregion, *_scrollup, *_scrolldown,
  121.             *_termcap_init, *_termcap_end;
  122. char  term_name[40];
  123. #ifndef USE_TERMINFO
  124. static char  _terminal[1024];         /* Storage for terminal entry */
  125. static char  _capabilities[1024];     /* String for cursor motion */
  126. static char *ptr = _capabilities;     /* for buffering         */
  127.  
  128. char  *tgetstr();                    /* Get termcap capability */
  129.  
  130. #endif
  131.  
  132. static enum  {NoScroll,UseScrollRegion,InsertDelete} _scrollmode;
  133.  
  134. char  *tgoto();                /* and the goto stuff    */
  135.  
  136.  
  137.  
  138. /*----------------------------------------------------------------------
  139.       Initialize the screen for output, set terminal type, etc
  140.  
  141.    Args: tt -- Pointer to variable to store the tty output structure.
  142.  
  143.  Result:  terminal size is discovered and set pine state
  144.           termcap entry is fetched and stored in local variables
  145.           make sure terminal has adequate capabilites
  146.           evaluate scrolling situation
  147.           returns status of indicating the state of the screen/termcap entry
  148.  
  149.       Returns:
  150.         -1 indicating no terminal name associated with this shell,
  151.         -2..-n  No termcap for this terminal type known
  152.     -3 Can't open termcap file 
  153.         -4 Terminal not powerful enough - missing clear to eoln or screen
  154.                                            or cursor motion
  155.  
  156.   ----*/
  157. int
  158. config_screen(tt, kbesc)
  159.      struct ttyo **tt;
  160.      KBESC_T     **kbesc;
  161. {
  162.     struct ttyo *ttyo;
  163.     char *getenv();
  164.     char *_ku, *_kd, *_kl, *_kr,
  165.      *_kppu, *_kppd, *_kphome, *_kpend, *_kpdel,
  166.      *_kf1, *_kf2, *_kf3, *_kf4, *_kf5, *_kf6,
  167.      *_kf7, *_kf8, *_kf9, *_kf10, *_kf11, *_kf12;
  168.  
  169. #ifdef USE_TERMINFO
  170.     int setupterm();
  171.     char *tigetstr();
  172.     char *ttnm;
  173.     int err;
  174.  
  175.     *tt = NULL;
  176.     ttnm = getenv ("TERM");
  177.     if (!ttnm) return -1;
  178.     strcpy (term_name, ttnm);
  179.     setupterm (term_name, 1 /* (ignored) */, &err);
  180.     switch (err) {
  181.     case -1 : return -3;
  182.     case 0 : return -2;
  183.     }
  184.  
  185.     ttyo = (struct ttyo *)fs_get(sizeof (struct ttyo));
  186.  
  187.     _line  =  0;        /* where are we right now?? */
  188.     _col   =  0;        /* assume zero, zero...     */
  189.  
  190.     /* load in all those pesky values */
  191.     _clearscreen       = tigetstr("clear");
  192.     _moveto            = tigetstr("cup");
  193.     _up                = tigetstr("cuu1");
  194.     _down              = tigetstr("cud1");
  195.     _right             = tigetstr("cuf1");
  196.     _left              = tigetstr("cub1");
  197.     _setinverse        = tigetstr("smso");
  198.     _clearinverse      = tigetstr("rmso");
  199.     _setunderline      = tigetstr("smul");
  200.     _clearunderline    = tigetstr("rmul");
  201.     _setbold           = tigetstr("bold");
  202.     _clearbold         = tigetstr("sgr0");
  203.     _cleartoeoln       = tigetstr("el");
  204.     _cleartoeos        = tigetstr("ed");
  205.     _deletechar        = tigetstr("dch1");
  206.     _insertchar        = tigetstr("ich1");
  207.     _startinsert       = tigetstr("smir");
  208.     _endinsert         = tigetstr("rmir");
  209.     _deleteline        = tigetstr("dl1");
  210.     _insertline        = tigetstr("il1");
  211.     _scrollregion      = tigetstr("csr");
  212.     _scrolldown        = tigetstr("ind");
  213.     _scrollup          = tigetstr("ri");
  214.     _termcap_init      = tigetstr("smcup");
  215.     _termcap_end       = tigetstr("rmcup");
  216.     _lines           = tigetnum("lines");
  217.     _columns           = tigetnum("cols");
  218.     _ku                = tigetstr("kcuu1");
  219.     _kd                = tigetstr("kcud1");
  220.     _kl                = tigetstr("kcub1");
  221.     _kr                = tigetstr("kcuf1");
  222.     _kppu              = tigetstr("kpp");
  223.     _kppd              = tigetstr("knp");
  224.     _kphome            = tigetstr("khome");
  225.     _kpend             = tigetstr("kend");
  226.     _kpdel             = tigetstr("kdch1");
  227.     _kf1               = tigetstr("kf1");
  228.     _kf2               = tigetstr("kf2");
  229.     _kf3               = tigetstr("kf3");
  230.     _kf4               = tigetstr("kf4");
  231.     _kf5               = tigetstr("kf5");
  232.     _kf6               = tigetstr("kf6");
  233.     _kf7               = tigetstr("kf7");
  234.     _kf8               = tigetstr("kf8");
  235.     _kf9               = tigetstr("kf9");
  236.     _kf10              = tigetstr("kf10");
  237.     _kf11              = tigetstr("kf11");
  238.     _kf12              = tigetstr("kf12");
  239. #else
  240.     char *ttnm;            /* tty name */
  241.     int   tgetent(),        /* get termcap entry */
  242.           err;
  243.  
  244.     *tt = NULL;
  245.     if (!(ttnm = getenv("TERM")) || !strcpy(term_name, ttnm))
  246.       return(-1);
  247.  
  248.     if ((err = tgetent(_terminal, term_name)) != 1)
  249.         return(err-2);
  250.  
  251.     ttyo = (struct ttyo *)fs_get(sizeof (struct ttyo));
  252.  
  253.     _line  =  0;        /* where are we right now?? */
  254.     _col   =  0;        /* assume zero, zero...     */
  255.  
  256.     /* load in all those pesky values */
  257.     ptr                = _capabilities;
  258.     _clearscreen       = tgetstr("cl", &ptr);
  259.     _moveto            = tgetstr("cm", &ptr);
  260.     _up                = tgetstr("up", &ptr);
  261.     _down              = tgetstr("do", &ptr);
  262.     _right             = tgetstr("nd", &ptr);
  263.     _left              = tgetstr("bs", &ptr);
  264.     _setinverse        = tgetstr("so", &ptr);
  265.     _clearinverse      = tgetstr("se", &ptr);
  266.     _setunderline      = tgetstr("us", &ptr);
  267.     _clearunderline    = tgetstr("ue", &ptr);
  268.     _setbold           = tgetstr("md", &ptr);
  269.     _clearbold         = tgetstr("me", &ptr);
  270.     _cleartoeoln       = tgetstr("ce", &ptr);
  271.     _cleartoeos        = tgetstr("cd", &ptr);
  272.     _deletechar        = tgetstr("dc", &ptr);
  273.     _insertchar        = tgetstr("ic", &ptr);
  274.     _startinsert       = tgetstr("im", &ptr);
  275.     _endinsert         = tgetstr("ei", &ptr);
  276.     _deleteline        = tgetstr("dl", &ptr);
  277.     _insertline        = tgetstr("al", &ptr);
  278.     _scrollregion      = tgetstr("cs", &ptr);
  279.     _scrolldown        = tgetstr("sf", &ptr);
  280.     _scrollup          = tgetstr("sr", &ptr);
  281.     _termcap_init      = tgetstr("ti", &ptr);
  282.     _termcap_end       = tgetstr("te", &ptr);
  283.     _lines           = tgetnum("li");
  284.     _columns           = tgetnum("co");
  285.     _ku                = tgetstr("ku", &ptr);
  286.     _kd                = tgetstr("kd", &ptr);
  287.     _kl                = tgetstr("kl", &ptr);
  288.     _kr                = tgetstr("kr", &ptr);
  289.     _kppu              = tgetstr("kP", &ptr);
  290.     _kppd              = tgetstr("kN", &ptr);
  291.     _kphome            = tgetstr("kh", &ptr);
  292.     _kpend             = tgetstr("kE", &ptr);
  293.     _kpdel             = tgetstr("kD", &ptr);
  294.     _kf1               = tgetstr("k1", &ptr);
  295.     _kf2               = tgetstr("k2", &ptr);
  296.     _kf3               = tgetstr("k3", &ptr);
  297.     _kf4               = tgetstr("k4", &ptr);
  298.     _kf5               = tgetstr("k5", &ptr);
  299.     _kf6               = tgetstr("k6", &ptr);
  300.     _kf7               = tgetstr("k7", &ptr);
  301.     _kf8               = tgetstr("k8", &ptr);
  302.     _kf9               = tgetstr("k9", &ptr);
  303.     if((_kf10          = tgetstr("k;", &ptr)) == NULL)
  304.       _kf10            = tgetstr("k0", &ptr);
  305.     _kf11              = tgetstr("F1", &ptr);
  306.     _kf12              = tgetstr("F2", &ptr);
  307. #endif
  308.  
  309.     if(_lines == -1) {
  310.     char *el;
  311.     int   ll;
  312.  
  313.         /* tgetnum failed, try $LINES */
  314.     el = getenv("LINES");
  315.     if(el && (ll = atoi(el)) > 0)
  316.       _lines = ll;
  317.     else
  318.           _lines = DEFAULT_LINES_ON_TERMINAL;
  319.     }
  320.     if(_columns == -1) {
  321.     char *ec;
  322.     int   cc;
  323.  
  324.         /* tgetnum failed, try $COLUMNS */
  325.     ec = getenv("COLUMNS");
  326.     if(ec && (cc = atoi(ec)) > 0)
  327.           _columns = cc;
  328.     else
  329.           _columns = DEFAULT_COLUMNS_ON_TERMINAL;
  330.     }
  331.  
  332.     get_windsize(ttyo);
  333.  
  334.     ttyo->header_rows = 2;
  335.     ttyo->footer_rows = 3;
  336.  
  337.     /*---- Make sure this terminal has the capability.
  338.         All we need is cursor address, clear line, and 
  339.         reverse video.
  340.       ---*/
  341.     if(_moveto == NULL || _cleartoeoln == NULL ||
  342.        _setinverse == NULL || _clearinverse == NULL) {
  343.           return(-4);
  344.     }
  345.  
  346.     dprint(1, (debugfile, "Terminal type: %s\n", term_name));
  347.  
  348.     /*------ Figure out scrolling mode -----*/
  349.     if(_scrollregion != NULL && _scrollregion[0] != '\0' &&
  350.           _scrollup != NULL && _scrollup[0] != '\0'){
  351.         _scrollmode = UseScrollRegion;
  352.     } else if(_insertline != NULL && _insertline[0] != '\0' &&
  353.        _deleteline != NULL && _deleteline[0] != '\0') {
  354.         _scrollmode = InsertDelete;
  355.     } else {
  356.         _scrollmode = NoScroll;
  357.     }
  358.     dprint(7, (debugfile, "Scroll mode: %s\n",
  359.                _scrollmode==NoScroll ? "No Scroll" :
  360.                _scrollmode==InsertDelete ? "InsertDelete" : "Scroll Regions"));
  361.  
  362.  
  363.     if (!_left) {
  364.         _left = "\b";
  365.     }
  366.  
  367.     *tt = ttyo;
  368.  
  369. #ifndef TERMCAP_WINS
  370.     /*
  371.      * Add default keypad sequences to the trie.
  372.      * Since these come first, they will override any conflicting termcap
  373.      * or terminfo escape sequences defined below.  An escape sequence is
  374.      * considered conflicting if one is a prefix of the other.
  375.      * So, without TERMCAP_WINS, there will likely be some termcap/terminfo
  376.      * escape sequences that don't work, because they conflict with default
  377.      * sequences defined here.
  378.      */
  379.     setup_dflt_esc_seq(kbesc);
  380. #endif /* !TERMCAP_WINS */
  381.  
  382.     /*
  383.      * add termcap/info escape sequences to the trie...
  384.      */
  385.  
  386.     if(_ku != NULL && _kd != NULL && _kl != NULL && _kr != NULL){
  387.     kpinsert(kbesc, _ku, KEY_UP);
  388.     kpinsert(kbesc, _kd, KEY_DOWN);
  389.     kpinsert(kbesc, _kl, KEY_LEFT);
  390.     kpinsert(kbesc, _kr, KEY_RIGHT);
  391.     }
  392.  
  393.     if(_kppu != NULL && _kppd != NULL){
  394.     kpinsert(kbesc, _kppu, KEY_PGUP);
  395.     kpinsert(kbesc, _kppd, KEY_PGDN);
  396.     }
  397.  
  398.     kpinsert(kbesc, _kphome, KEY_HOME);
  399.     kpinsert(kbesc, _kpend,  KEY_END);
  400.     kpinsert(kbesc, _kpdel,  KEY_DEL);
  401.  
  402.     kpinsert(kbesc, _kf1,  PF1);
  403.     kpinsert(kbesc, _kf2,  PF2);
  404.     kpinsert(kbesc, _kf3,  PF3);
  405.     kpinsert(kbesc, _kf4,  PF4);
  406.     kpinsert(kbesc, _kf5,  PF5);
  407.     kpinsert(kbesc, _kf6,  PF6);
  408.     kpinsert(kbesc, _kf7,  PF7);
  409.     kpinsert(kbesc, _kf8,  PF8);
  410.     kpinsert(kbesc, _kf9,  PF9);
  411.     kpinsert(kbesc, _kf10, PF10);
  412.     kpinsert(kbesc, _kf11, PF11);
  413.     kpinsert(kbesc, _kf12, PF12);
  414.  
  415. #ifdef TERMCAP_WINS
  416.     /*
  417.      * Add default keypad sequences to the trie.
  418.      * Since these come after the termcap/terminfo escape sequences above,
  419.      * the termcap/info sequences will override any conflicting default
  420.      * escape sequences defined here.
  421.      * So, with TERMCAP_WINS, some of the default sequences will be missing.
  422.      * This means that you'd better get all of your termcap/terminfo entries
  423.      * correct if you define TERMCAP_WINS.
  424.      */
  425.     setup_dflt_esc_seq(kbesc);
  426. #endif /* TERMCAP_WINS */
  427.  
  428.     return(0);
  429. }
  430.  
  431.  
  432.  
  433. /*----------------------------------------------------------------------
  434.    Initialize the screen with the termcap string 
  435.   ----*/
  436. void
  437. init_screen()
  438. {
  439.     if(_termcap_init)            /* init using termcap's rule */
  440.       tputs(_termcap_init, 1, outchar);
  441.  
  442.     /* and make sure there are no scrolling surprises! */
  443.     BeginScroll(0, ps_global->ttyo->screen_rows - 1);
  444.     /* and make sure icon text starts out consistent */
  445.     icon_text(NULL);
  446.     fflush(stdout);
  447. }
  448.         
  449.  
  450.  
  451.  
  452. /*----------------------------------------------------------------------
  453.        Get the current window size
  454.   
  455.    Args: ttyo -- pointer to structure to store window size in
  456.  
  457.   NOTE: we don't override the given values unless we know better
  458.  ----*/
  459. int
  460. get_windsize(ttyo)
  461. struct ttyo *ttyo;     
  462. {
  463. #ifdef RESIZING 
  464.     struct winsize win;
  465.  
  466.     /*
  467.      * Get the window size from the tty driver.  If we can't fish it from
  468.      * stdout (pine's output is directed someplace else), try stdin (which
  469.      * *must* be associated with the terminal; see init_tty_driver)...
  470.      */
  471.     if(ioctl(1, TIOCGWINSZ, &win) >= 0            /* 1 is stdout */
  472.     || ioctl(0, TIOCGWINSZ, &win) >= 0){        /* 0 is stdin */
  473.     if(win.ws_row)
  474.       _lines = min(win.ws_row, MAX_SCREEN_ROWS);
  475.  
  476.     if(win.ws_col)
  477.       _columns  = min(win.ws_col, MAX_SCREEN_COLS);
  478.  
  479.         dprint(2, (debugfile, "new win size -----<%d %d>------\n",
  480.                    _lines, _columns));
  481.     }
  482.     else
  483.       /* Depending on the OS, the ioctl() may have failed because
  484.      of a 0 rows, 0 columns setting.  That happens on DYNIX/ptx 1.3
  485.      (with a kernel patch that happens to involve the negotiation
  486.      of window size in the telnet streams module.)  In this case
  487.      the error is EINVARG.  Leave the default settings. */
  488.       dprint(1, (debugfile, "ioctl(TIOCWINSZ) failed :%s\n",
  489.          error_description(errno)));
  490. #endif
  491.  
  492.     ttyo->screen_cols = min(_columns, MAX_SCREEN_COLS);
  493.     ttyo->screen_rows = min(_lines, MAX_SCREEN_ROWS);
  494.     return(0);
  495. }
  496.  
  497.  
  498. /*----------------------------------------------------------------------
  499.       End use of the screen.
  500.       Print status message, if any.
  501.       Flush status messages.
  502.   ----*/
  503. void
  504. end_screen(message)
  505.     char *message;
  506. {
  507.     int footer_rows_was_one = 0;
  508.  
  509.     dprint(9, (debugfile, "end_screen called\n"));
  510.  
  511.     if(FOOTER_ROWS(ps_global) == 1){
  512.     footer_rows_was_one++;
  513.     FOOTER_ROWS(ps_global) = 3;
  514.     mark_status_unknown();
  515.     }
  516.  
  517.     flush_status_messages(1);
  518.     blank_keymenu(_lines - 2, 0);
  519.     MoveCursor(_lines - 2, 0);
  520.     if(_termcap_end != NULL)
  521.       tputs(_termcap_end, 1, outchar);
  522.  
  523.     if(message){
  524.     printf("%s\r\n", message);
  525.     }
  526.  
  527.     fflush(stdout);
  528.  
  529.     if(footer_rows_was_one){
  530.     FOOTER_ROWS(ps_global) = 1;
  531.     mark_status_unknown();
  532.     }
  533. }
  534.     
  535.  
  536.  
  537. /*----------------------------------------------------------------------
  538.      Clear the terminal screen
  539.  
  540.  Result: The screen is cleared
  541.          internal cursor position set to 0,0
  542.   ----*/
  543. void
  544. ClearScreen()
  545. {
  546.     _line = 0;    /* clear leaves us at top... */
  547.     _col  = 0;
  548.  
  549.     if(ps_global->in_init_seq)
  550.       return;
  551.  
  552.     mark_status_unknown();
  553.     mark_keymenu_dirty();
  554.     mark_titlebar_dirty();
  555.  
  556.     if(!_clearscreen){
  557.     ClearLines(0, _lines-1);
  558.         MoveCursor(0, 0);
  559.     }
  560.     else{
  561.     tputs(_clearscreen, 1, outchar);
  562.         moveabsolute(0, 0);  /* some clearscreens don't move correctly */
  563.     }
  564. }
  565.  
  566.  
  567. /*----------------------------------------------------------------------
  568.             Internal move cursor to absolute position
  569.  
  570.   Args: col -- column to move cursor to
  571.         row -- row to move cursor to
  572.  
  573.  Result: cursor is moved (variables, not updates)
  574.   ----*/
  575.  
  576. static void
  577. moveabsolute(col, row)
  578. {
  579.  
  580.     char *stuff, *tgoto();
  581.  
  582.     stuff = tgoto(_moveto, col, row);
  583.     tputs(stuff, 1, outchar);
  584. }
  585.  
  586.  
  587. /*----------------------------------------------------------------------
  588.         Move the cursor to the row and column number
  589.   Args:  row number
  590.          column number
  591.  
  592.  Result: Cursor moves
  593.          internal position updated
  594.   ----*/
  595. void
  596. MoveCursor(row, col)
  597.      int row, col;
  598. {
  599.     /** move cursor to the specified row column on the screen.
  600.         0,0 is the top left! **/
  601.  
  602.     int scrollafter = 0;
  603.  
  604.     /* we don't want to change "rows" or we'll mangle scrolling... */
  605.  
  606.     if(ps_global->in_init_seq)
  607.       return;
  608.  
  609.     if (col < 0)
  610.       col = 0;
  611.     if (col >= ps_global->ttyo->screen_cols)
  612.       col = ps_global->ttyo->screen_cols - 1;
  613.     if (row < 0)
  614.       row = 0;
  615.     if (row > ps_global->ttyo->screen_rows) {
  616.       if (col == 0)
  617.         scrollafter = row - ps_global->ttyo->screen_rows;
  618.       row = ps_global->ttyo->screen_rows;
  619.     }
  620.  
  621.     if (!_moveto)
  622.         return;
  623.  
  624.     if (row == _line) {
  625.       if (col == _col)
  626.         return;                /* already there! */
  627.  
  628.       else if (abs(col - _col) < 5) {    /* within 5 spaces... */
  629.         if (col > _col && _right)
  630.           CursorRight(col - _col);
  631.         else if (col < _col &&  _left)
  632.           CursorLeft(_col - col);
  633.         else
  634.           moveabsolute(col, row);
  635.       }
  636.       else         /* move along to the new x,y loc */
  637.         moveabsolute(col, row);
  638.     }
  639.     else if (col == _col && abs(row - _line) < 5) {
  640.       if (row < _line && _up)
  641.         CursorUp(_line - row);
  642.       else if (_line > row && _down)
  643.         CursorDown(row - _line);
  644.       else
  645.         moveabsolute(col, row);
  646.     }
  647.     else if (_line == row-1 && col == 0) {
  648.       putchar('\n');    /* that's */
  649.       putchar('\r');    /*  easy! */
  650.     }
  651.     else 
  652.       moveabsolute(col, row);
  653.  
  654.     _line = row;    /* to ensure we're really there... */
  655.     _col  = col;
  656.  
  657.     if (scrollafter) {
  658.       while (scrollafter--) {
  659.         putchar('\n');
  660.         putchar('\r');
  661.  
  662.       }
  663.     }
  664.  
  665.     return;
  666. }
  667.  
  668.  
  669.  
  670. /*----------------------------------------------------------------------
  671.          Newline, move the cursor to the start of next line
  672.  
  673.  Result: Cursor moves
  674.   ----*/
  675. void
  676. NewLine()
  677. {
  678.    /** move the cursor to the beginning of the next line **/
  679.  
  680.     Writechar('\n', 0);
  681.     Writechar('\r', 0);
  682. }
  683.  
  684.  
  685.  
  686. /*----------------------------------------------------------------------
  687.         Move cursor up n lines with terminal escape sequence
  688.  
  689.    Args:  n -- number of lines to go up
  690.  
  691.  Result: cursor moves, 
  692.          internal position updated
  693.  
  694.  Only for ttyout use; not outside callers
  695.   ----*/
  696. static void
  697. CursorUp(n)
  698. int n;
  699. {
  700.     /** move the cursor up 'n' lines **/
  701.     /** Calling function must check that _up is not null before calling **/
  702.  
  703.     _line = (_line-n > 0? _line - n: 0);    /* up 'n' lines... */
  704.  
  705.     while (n-- > 0)
  706.       tputs(_up, 1, outchar);
  707. }
  708.  
  709.  
  710.  
  711. /*----------------------------------------------------------------------
  712.         Move cursor down n lines with terminal escape sequence
  713.  
  714.     Arg: n -- number of lines to go down
  715.  
  716.  Result: cursor moves, 
  717.          internal position updated
  718.  
  719.  Only for ttyout use; not outside callers
  720.   ----*/
  721. static void
  722. CursorDown(n)
  723.      int          n;
  724. {
  725.     /** move the cursor down 'n' lines **/
  726.     /** Caller must check that _down is not null before calling **/
  727.  
  728.     _line = (_line+n < ps_global->ttyo->screen_rows ? _line + n
  729.              : ps_global->ttyo->screen_rows);
  730.                                                /* down 'n' lines... */
  731.  
  732.     while (n-- > 0)
  733.         tputs(_down, 1, outchar);
  734. }
  735.  
  736.  
  737.  
  738. /*----------------------------------------------------------------------
  739.         Move cursor left n lines with terminal escape sequence
  740.  
  741.    Args:  n -- number of lines to go left
  742.  
  743.  Result: cursor moves, 
  744.          internal position updated
  745.  
  746.  Only for ttyout use; not outside callers
  747.   ----*/
  748. static void 
  749. CursorLeft(n)
  750. int n;
  751. {
  752.     /** move the cursor 'n' characters to the left **/
  753.     /** Caller must check that _left is not null before calling **/
  754.  
  755.     _col = (_col - n> 0? _col - n: 0);    /* left 'n' chars... */
  756.  
  757.     while (n-- > 0)
  758.       tputs(_left, 1, outchar);
  759. }
  760.  
  761.  
  762. /*----------------------------------------------------------------------
  763.         Move cursor right n lines with terminal escape sequence
  764.  
  765.    Args:  number of lines to go right
  766.  
  767.  Result: cursor moves, 
  768.          internal position updated
  769.  
  770.  Only for ttyout use; not outside callers
  771.   ----*/
  772. static void 
  773. CursorRight(n)
  774. int n;
  775. {
  776.     /** move the cursor 'n' characters to the right (nondestructive) **/
  777.     /** Caller must check that _right is not null before calling **/
  778.  
  779.     _col = (_col+n < ps_global->ttyo->screen_cols? _col + n :
  780.              ps_global->ttyo->screen_cols);    /* right 'n' chars... */
  781.  
  782.     while (n-- > 0)
  783.       tputs(_right, 1, outchar);
  784.  
  785. }
  786.  
  787.  
  788.  
  789. /*----------------------------------------------------------------------
  790.        Start painting inverse on the screen
  791.  
  792.  Result: escape sequence to go into inverse is output
  793.          returns 1 if it was done, 0 if not.
  794.   ----*/
  795. int
  796. StartInverse()
  797. {
  798.     /** set inverse video mode **/
  799.  
  800.     if (!_setinverse)
  801.         return(0);
  802.     
  803.     if(_in_inverse)
  804.       return(1);
  805.  
  806.     _in_inverse = 1;
  807.     tputs(_setinverse, 1, outchar);
  808.     return(1);
  809. }
  810.  
  811.  
  812.  
  813. /*----------------------------------------------------------------------
  814.       End painting inverse on the screen
  815.  
  816.  Result: escape sequence to go out of inverse is output
  817.          returns 1 if it was done, 0 if not.
  818.   ----------------------------------------------------------------------*/
  819. void
  820. EndInverse()
  821. {
  822.     /** compliment of startinverse **/
  823.  
  824.     if (!_clearinverse)
  825.         return;
  826.  
  827.     if(_in_inverse){
  828.     _in_inverse = 0;
  829.     tputs(_clearinverse, 1, outchar);
  830.     }
  831. }
  832.  
  833.  
  834. int
  835. StartUnderline()
  836. {
  837.     if (!_setunderline)
  838.         return(0);
  839.  
  840.     tputs(_setunderline, 1, outchar);
  841.     return(1);
  842. }
  843.  
  844.  
  845. void
  846. EndUnderline()
  847. {
  848.     if (!_clearunderline)
  849.         return;
  850.  
  851.     tputs(_clearunderline, 1, outchar);
  852. }
  853.  
  854. int
  855. StartBold()
  856. {
  857.     if (!_setbold)
  858.         return(0);
  859.  
  860.     tputs(_setbold, 1, outchar);
  861.     return(1);
  862. }
  863.  
  864. void
  865. EndBold()
  866. {
  867.     if (!_clearbold)
  868.         return;
  869.  
  870.     tputs(_clearbold, 1, outchar);
  871. }
  872.  
  873.  
  874.  
  875. /*----------------------------------------------------------------------
  876.        Insert character on screen pushing others right
  877.  
  878.    Args: c --  character to insert
  879.  
  880.  Result: charcter is inserted if possible
  881.          return -1 if it can't be done
  882.   ----------------------------------------------------------------------*/
  883. InsertChar(c)
  884.      int c;
  885. {
  886.     if(_insertchar != NULL && *_insertchar != '\0') {
  887.     tputs(_insertchar, 1, outchar);
  888.     Writechar(c, 0);
  889.     } else if(_startinsert != NULL && *_startinsert != '\0') {
  890.     tputs(_startinsert, 1, outchar);
  891.     Writechar(c, 0);
  892.     tputs(_endinsert, 1, outchar);
  893.     } else {
  894.     return(-1);
  895.     }
  896.     return(0);
  897. }
  898.  
  899.  
  900.  
  901. /*----------------------------------------------------------------------
  902.          Delete n characters from line, sliding rest of line left
  903.  
  904.    Args: n -- number of characters to delete
  905.  
  906.  
  907.  Result: characters deleted on screen
  908.          returns -1 if it wasn't done
  909.   ----------------------------------------------------------------------*/
  910. DeleteChar(n)
  911.      int n;
  912. {
  913.     if(_deletechar == NULL || *_deletechar == '\0')
  914.       return(-1);
  915.  
  916.     while(n) {
  917.     tputs(_deletechar, 1, outchar);
  918.     n--;
  919.     }
  920.     return(0);
  921. }
  922.  
  923.  
  924.  
  925. /*----------------------------------------------------------------------
  926.   Go into scrolling mode, that is set scrolling region if applicable
  927.  
  928.    Args: top    -- top line of region to scroll
  929.          bottom -- bottom line of region to scroll
  930.      (These are zero-origin numbers)
  931.  
  932.  Result: either set scrolling region or
  933.          save values for later scrolling
  934.          returns -1 if we can't scroll
  935.  
  936.  Unfortunately this seems to leave the cursor in an unpredictable place
  937.  at least the manuals don't say where, so we force it here.
  938. -----*/
  939. static int __t, __b;
  940.  
  941. BeginScroll(top, bottom)
  942.      int top, bottom;
  943. {
  944.     char *stuff;
  945.  
  946.     if(_scrollmode == NoScroll)
  947.       return(-1);
  948.  
  949.     __t = top;
  950.     __b = bottom;
  951.     if(_scrollmode == UseScrollRegion){
  952.         stuff = tgoto(_scrollregion, bottom, top);
  953.         tputs(stuff, 1, outchar);
  954.         /*-- a location  very far away to force a cursor address --*/
  955.         _line = FARAWAY;
  956.         _col  = FARAWAY;
  957.     }
  958.     return(0);
  959. }
  960.  
  961.  
  962.  
  963. /*----------------------------------------------------------------------
  964.    End scrolling -- clear scrolling regions if necessary
  965.  
  966.  Result: Clear scrolling region on terminal
  967.   -----*/
  968. void
  969. EndScroll()
  970. {
  971.     if(_scrollmode == UseScrollRegion && _scrollregion != NULL){
  972.     /* Use tgoto even though we're not cursor addressing because
  973.            the format of the capability is the same.
  974.          */
  975.         char *stuff = tgoto(_scrollregion, ps_global->ttyo->screen_rows -1, 0);
  976.     tputs(stuff, 1, outchar);
  977.         /*-- a location  very far away to force a cursor address --*/
  978.         _line = FARAWAY;
  979.         _col  = FARAWAY;
  980.     }
  981. }
  982.  
  983.  
  984. /* ----------------------------------------------------------------------
  985.     Scroll the screen using insert/delete or scrolling regions
  986.  
  987.    Args:  lines -- number of lines to scroll, positive forward
  988.  
  989.  Result: Screen scrolls
  990.          returns 0 if scroll succesful, -1 if not
  991.  
  992.  positive lines goes foward (new lines come in at bottom
  993.  Leaves cursor at the place to insert put new text
  994.  
  995.  0,0 is the upper left
  996.  -----*/
  997. ScrollRegion(lines)
  998.     int lines;
  999. {
  1000.     int l;
  1001.  
  1002.     if(lines == 0)
  1003.       return(0);
  1004.  
  1005.     if(_scrollmode == UseScrollRegion) {
  1006.     if(lines > 0) {
  1007.         MoveCursor(__b, 0);
  1008.         for(l = lines ; l > 0 ; l--)
  1009.           tputs((_scrolldown == NULL || _scrolldown[0] =='\0') ? "\n" :
  1010.             _scrolldown, 1, outchar);
  1011.     } else {
  1012.         MoveCursor(__t, 0);
  1013.         for(l = -lines; l > 0; l--)
  1014.           tputs(_scrollup, 1, outchar);
  1015.     }
  1016.     } else if(_scrollmode == InsertDelete) {
  1017.     if(lines > 0) {
  1018.         MoveCursor(__t, 0);
  1019.         for(l = lines; l > 0; l--) 
  1020.           tputs(_deleteline, 1, outchar);
  1021.         MoveCursor(__b, 0);
  1022.         for(l = lines; l > 0; l--) 
  1023.           tputs(_insertline, 1, outchar);
  1024.     } else {
  1025.         for(l = -lines; l > 0; l--) {
  1026.             MoveCursor(__b, 0);
  1027.             tputs(_deleteline, 1, outchar);
  1028.         MoveCursor(__t, 0);
  1029.         tputs(_insertline, 1, outchar);
  1030.         }
  1031.     }
  1032.     } else {
  1033.     return(-1);
  1034.     }
  1035.     fflush(stdout);
  1036.     return(0);
  1037. }
  1038.  
  1039.  
  1040.  
  1041. /*----------------------------------------------------------------------
  1042.     Write a character to the screen, keeping track of cursor position
  1043.  
  1044.    Args: ch -- character to output
  1045.  
  1046.  Result: character output
  1047.          cursor position variables updated
  1048.   ----*/
  1049. Writechar(ch, new_esc_len)
  1050.      register unsigned int ch;
  1051.      int      new_esc_len;
  1052. {
  1053.     register int nt;
  1054.     static   int esc_len = 0;
  1055.  
  1056.     if(ps_global->in_init_seq                /* silent */
  1057.        || (F_ON(F_BLANK_KEYMENU, ps_global)        /* or bottom, */
  1058.        && !esc_len                    /* right cell */
  1059.        && _line + 1 == ps_global->ttyo->screen_rows
  1060.        && _col + 1 == ps_global->ttyo->screen_cols))
  1061.       return;
  1062.  
  1063.     if(!iscntrl(ch & 0x7f)){
  1064.     putchar(ch);
  1065.     if(esc_len > 0)
  1066.       esc_len--;
  1067.     else
  1068.       _col++;
  1069.     }
  1070.     else{
  1071.     switch(ch){
  1072.       case LINE_FEED:
  1073.         /*-- Don't have to watch out for auto wrap or newline glitch
  1074.           because we never let it happen. See below
  1075.           ---*/
  1076.         putchar('\n');
  1077.         _line = min(_line+1,ps_global->ttyo->screen_rows);
  1078.         esc_len = 0;
  1079.         break;
  1080.  
  1081.       case RETURN :        /* move to column 0 */
  1082.         putchar('\r');
  1083.         _col = 0;
  1084.         esc_len = 0;
  1085.         break;
  1086.  
  1087.       case BACKSPACE :    /* move back a space if not in column 0 */
  1088.         if(_col != 0) {
  1089.         putchar('\b');
  1090.         _col--;
  1091.         }            /* else BACKSPACE does nothing */
  1092.  
  1093.         break;
  1094.  
  1095.       case BELL :        /* ring the bell but don't advance _col */
  1096.         putchar(ch);
  1097.         break;
  1098.  
  1099.       case TAB :        /* if a tab, output it */
  1100.         do            /* BUG? ignores tty driver's spacing */
  1101.           putchar(' ');
  1102.         while(_col < ps_global->ttyo->screen_cols - 1
  1103.           && ((++_col)&0x07) != 0);
  1104.         break;
  1105.  
  1106.       case ESCAPE :
  1107.         /* If we're outputting an escape here, it may be part of an iso2022
  1108.            escape sequence in which case take up no space on the screen.
  1109.            Unfortunately such sequences are variable in length.
  1110.            */
  1111.         esc_len = new_esc_len - 1;
  1112.         putchar(ch);
  1113.         break;
  1114.  
  1115.       default :        /* Change remaining control characters to ? */
  1116.         if(F_ON(F_PASS_CONTROL_CHARS, ps_global))
  1117.           putchar(ch);
  1118.         else
  1119.           putchar('?');
  1120.  
  1121.         if(esc_len > 0)
  1122.           esc_len--;
  1123.         else
  1124.           _col++;
  1125.  
  1126.         break;
  1127.     }
  1128.     }
  1129.  
  1130.  
  1131.     /* Here we are at the end of the line. We've decided to make no
  1132.        assumptions about how the terminal behaves at this point.
  1133.        What can happen now are the following
  1134.            1. Cursor is at start of next line, and next character will
  1135.               apear there. (autowrap, !newline glitch)
  1136.            2. Cursor is at start of next line, and if a newline is output
  1137.               it'll be ignored. (autowrap, newline glitch)
  1138.            3. Cursor is still at end of line and next char will apear
  1139.               there over the top of what is there now (no autowrap).
  1140.        We ignore all this and force the cursor to the next line, just 
  1141.        like case 1. A little expensive but worth it to avoid problems
  1142.        with terminals configured so they don't match termcap
  1143.        */
  1144.     if(_col == ps_global->ttyo->screen_cols) {
  1145.         _col = 0;
  1146.         if(_line + 1 < ps_global->ttyo->screen_rows)
  1147.       _line++;
  1148.  
  1149.     moveabsolute(_col, _line);
  1150.     }
  1151.  
  1152.     return(0);
  1153. }
  1154.  
  1155.  
  1156.  
  1157. /*----------------------------------------------------------------------
  1158.        Write string to screen at current cursor position
  1159.  
  1160.    Args: string -- strings to be output
  1161.  
  1162.  Result: Line written to the screen
  1163.   ----*/
  1164. void
  1165. Write_to_screen(string)                /* UNIX */
  1166.       register char *string; 
  1167. {
  1168.     while(*string)
  1169.       Writechar((unsigned char) *string++, 0);
  1170. }
  1171.  
  1172.  
  1173.  
  1174. /*----------------------------------------------------------------------
  1175.     Clear screen to end of line on current line
  1176.  
  1177.  Result: Line is cleared
  1178.   ----*/
  1179. void
  1180. CleartoEOLN()
  1181. {
  1182.     if(!_cleartoeoln)
  1183.       return;
  1184.  
  1185.     tputs(_cleartoeoln, 1, outchar);
  1186. }
  1187.  
  1188.  
  1189.  
  1190. /*----------------------------------------------------------------------
  1191.      Clear screen to end of screen from current point
  1192.  
  1193.  Result: screen is cleared
  1194.   ----*/
  1195. CleartoEOS()
  1196. {
  1197.     if(!_cleartoeos){
  1198.         CleartoEOLN();
  1199.     ClearLines(_line, _lines-1);
  1200.     }
  1201.     else
  1202.       tputs(_cleartoeos, 1, outchar);
  1203. }
  1204.  
  1205.  
  1206.  
  1207. /*----------------------------------------------------------------------
  1208.      function to output character used by termcap
  1209.  
  1210.    Args: c -- character to output
  1211.  
  1212.  Result: character output to screen via stdio
  1213.   ----*/
  1214. void
  1215. outchar(c)
  1216. int c;
  1217. {
  1218.     /** output the given character.  From tputs... **/
  1219.     /** Note: this CANNOT be a macro!              **/
  1220.  
  1221.     putc((unsigned char)c, stdout);
  1222. }
  1223.  
  1224.  
  1225.  
  1226. /*----------------------------------------------------------------------
  1227.      function to output string such that it becomes icon text
  1228.  
  1229.    Args: s -- string to write
  1230.  
  1231.  Result: string indicated become our "icon" text
  1232.   ----*/
  1233. void
  1234. icon_text(s)
  1235.     char *s;
  1236. {
  1237.     if(F_ON(F_ENABLE_XTERM_NEWMAIL, ps_global) && getenv("DISPLAY")){
  1238.     fputs("\033]1;", stdout);
  1239.     fputs((s) ? s : ps_global->pine_name, stdout);
  1240.     fputs("\007", stdout);
  1241.     fflush(stdout);
  1242.     }
  1243. }
  1244.  
  1245.  
  1246.  
  1247. #else /* DOS && OS2 */  /* Middle of giant ifdef for DOS & OS2 drivers */
  1248.  
  1249.  
  1250. /*----------------------------------------------------------------------
  1251.       Initialize the screen for output, set terminal type, etc
  1252.  
  1253.  Input: TERM and TERMCAP environment variables
  1254.         Pointer to variable to store the tty output structure.
  1255.  
  1256.  Result:  terminal size is discovered and set pine state
  1257.           termcap entry is fetched and stored in local variables
  1258.           make sure terminal has adequate capabilites
  1259.           evaluate scrolling situation
  1260.           returns status of indicating the state of the screen/termcap entry
  1261.   ----------------------------------------------------------------------*/
  1262. void
  1263. init_screen()                    /* DOS */
  1264. {
  1265.     return;                    /* NO OP */
  1266. }
  1267.  
  1268.  
  1269.  
  1270. /*----------------------------------------------------------------------
  1271.       End use of the screen. 
  1272.   ----------------------------------------------------------------------*/
  1273. void
  1274. end_screen(message)                /* DOS */
  1275.     char *message;
  1276. {
  1277.     extern void exit_text_mode();
  1278.     int footer_rows_was_one = 0;
  1279.  
  1280.     if(FOOTER_ROWS(ps_global) == 1){
  1281.     footer_rows_was_one++;
  1282.     FOOTER_ROWS(ps_global) = 3;
  1283.     mark_status_unknown();
  1284.     }
  1285.  
  1286.     flush_status_messages(1);
  1287.  
  1288.     blank_keymenu(_lines - 2, 0);
  1289.  
  1290.     if(message){
  1291.     StartInverse();
  1292.     PutLine0(_lines - 2, 0, message);
  1293.     }
  1294.     
  1295.     EndInverse();
  1296.  
  1297.     MoveCursor(_lines - 1, 0);
  1298. #ifndef _WINDOWS
  1299.     exit_text_mode(NULL);
  1300. #endif
  1301.     ibmclose();
  1302.     if(footer_rows_was_one){
  1303.     FOOTER_ROWS(ps_global) = 1;
  1304.     mark_status_unknown();
  1305.     }
  1306. }
  1307.  
  1308. #ifdef OS2
  1309. static void
  1310. get_dimen(int *width, int *length)
  1311. {
  1312.     VIOMODEINFO vm;
  1313.     vm.cb = sizeof vm;
  1314.     VioGetMode(&vm, 0);
  1315.     *width = vm.col;
  1316.     *length = vm.row;
  1317. }
  1318. #endif
  1319.  
  1320.  
  1321. /*----------------------------------------------------------------------
  1322.       Initialize the screen for output, set terminal type, etc
  1323.  
  1324.    Args: tt -- Pointer to variable to store the tty output structure.
  1325.  
  1326.  Result:  terminal size is discovered and set pine state
  1327.           termcap entry is fetched and stored in local variables
  1328.           make sure terminal has adequate capabilites
  1329.           evaluate scrolling situation
  1330.           returns status of indicating the state of the screen/termcap entry
  1331.  
  1332.       Returns:
  1333.         -1 indicating no terminal name associated with this shell,
  1334.         -2..-n  No termcap for this terminal type known
  1335.     -3 Can't open termcap file 
  1336.         -4 Terminal not powerful enough - missing clear to eoln or screen
  1337.                                            or cursor motion
  1338.  
  1339.   ----*/
  1340. int
  1341. config_screen(tt, kbesc)            /* DOS */
  1342.      struct ttyo **tt;
  1343.      KBESC_T     **kbesc;
  1344. {
  1345.     struct ttyo *ttyo;
  1346. #ifndef _WINDOWS
  1347.     extern void enter_text_mode();
  1348. #endif
  1349.  
  1350.     _line  =  0;        /* where are we right now?? */
  1351.     _col   =  0;        /* assume zero, zero...     */
  1352.  
  1353. #ifdef _WINDOWS
  1354.     mswin_getscreensize(&_lines, &_columns);
  1355.     if (_lines > MAX_SCREEN_ROWS)
  1356.     _lines = MAX_SCREEN_ROWS;
  1357.     if (_columns > MAX_SCREEN_COLS)
  1358.     _columns = MAX_SCREEN_COLS;
  1359. #else
  1360. #ifdef OS2
  1361.     get_dimen(&_columns, &_lines);
  1362. #else
  1363.     _lines   = DEFAULT_LINES_ON_TERMINAL;
  1364.     _columns = DEFAULT_COLUMNS_ON_TERMINAL;
  1365. #endif
  1366. #endif
  1367.     ttyo = (struct ttyo *)fs_get(sizeof(struct ttyo));
  1368.     ttyo->screen_cols = _columns;
  1369.     ttyo->screen_rows = _lines ;
  1370.     ttyo->header_rows = 2;
  1371.     ttyo->footer_rows = 3;
  1372.  
  1373. #ifndef _WINDOWS
  1374.     enter_text_mode(NULL);
  1375. #endif
  1376.     ibmopen();
  1377.  
  1378.     *tt = ttyo;
  1379.  
  1380.     return(0);
  1381. }
  1382.  
  1383.  
  1384.     
  1385. /*----------------------------------------------------------------------
  1386.        Get the current window size
  1387.   
  1388.    Args: ttyo -- pointer to structure to store window size in
  1389.  
  1390.   NOTE: we don't override the given values unless we know better
  1391.  ----*/
  1392. int
  1393. get_windsize(ttyo)                /* DOS */
  1394. struct ttyo *ttyo;     
  1395. {
  1396. #ifdef _WINDOWS
  1397.     char    fontName[LF_FACESIZE+1];
  1398.     char    fontSize[12];
  1399.     char    fontStyle[64];
  1400.     char    windowPosition[32];
  1401.     int        newRows, newCols;
  1402.     
  1403.         
  1404.     /* Get the new window parameters and update the 'pinerc' variables. */
  1405.     mswin_getwindow (fontName, fontSize, fontStyle, windowPosition);
  1406.     if(!ps_global->VAR_FONT_NAME
  1407.        || strucmp(ps_global->VAR_FONT_NAME, fontName))
  1408.       set_variable(V_FONT_NAME, fontName, 0);
  1409.  
  1410.     if(!ps_global->VAR_FONT_SIZE
  1411.        || strucmp(ps_global->VAR_FONT_SIZE, fontSize))
  1412.       set_variable(V_FONT_SIZE, fontSize, 0);
  1413.  
  1414.     if(!ps_global->VAR_FONT_STYLE
  1415.        || strucmp(ps_global->VAR_FONT_STYLE, fontStyle))
  1416.       set_variable(V_FONT_STYLE, fontStyle, 0);
  1417.  
  1418.     if(!ps_global->VAR_WINDOW_POSITION
  1419.        || strucmp(ps_global->VAR_WINDOW_POSITION, windowPosition))
  1420.       set_variable(V_WINDOW_POSITION, windowPosition, 0);
  1421.  
  1422.     mswin_getprintfont (fontName, fontSize, fontStyle);
  1423.     if(!ps_global->VAR_PRINT_FONT_NAME
  1424.        || strucmp(ps_global->VAR_PRINT_FONT_NAME, fontName))
  1425.       set_variable(V_PRINT_FONT_NAME, fontName, 0);
  1426.  
  1427.     if(!ps_global->VAR_PRINT_FONT_SIZE
  1428.        || strucmp(ps_global->VAR_PRINT_FONT_SIZE, fontSize))
  1429.       set_variable(V_PRINT_FONT_SIZE, fontSize, 0);
  1430.  
  1431.     if(!ps_global->VAR_PRINT_FONT_STYLE
  1432.        || strucmp(ps_global->VAR_PRINT_FONT_STYLE, fontStyle))
  1433.       set_variable(V_PRINT_FONT_STYLE, fontStyle, 0);
  1434.  
  1435.     /* Get new window size.  Compare to old.  The window may have just
  1436.      * moved, in which case we don't bother updating the size. */
  1437.     mswin_getscreensize(&newRows, &newCols);
  1438.     if (newRows == ttyo->screen_rows && newCols == ttyo->screen_cols)
  1439.         return (NO_OP_COMMAND);
  1440.  
  1441.     /* True resize. */
  1442.     ttyo->screen_rows = newRows;
  1443.     ttyo->screen_cols = newCols;
  1444.  
  1445.     if (ttyo->screen_rows > MAX_SCREEN_ROWS)
  1446.     ttyo->screen_rows = MAX_SCREEN_ROWS;
  1447.     if (ttyo->screen_cols > MAX_SCREEN_COLS)
  1448.     ttyo->screen_cols = MAX_SCREEN_COLS;
  1449.  
  1450.     return(KEY_RESIZE);
  1451. #else
  1452. #ifdef OS2
  1453.     get_dimen(&_columns, &_lines);
  1454. #endif
  1455.  
  1456.     ttyo->screen_cols = _columns;
  1457.     ttyo->screen_rows = _lines;
  1458.     return(0);
  1459. #endif
  1460. }
  1461.     
  1462.  
  1463.  
  1464.  
  1465. /*----------------------------------------------------------------------
  1466.      Clear the terminal screen
  1467.  
  1468.  Input:  none
  1469.  
  1470.  Result: The screen is cleared
  1471.          internal cursor position set to 0,0
  1472.   ----------------------------------------------------------------------*/
  1473. void
  1474. ClearScreen()                    /* DOS */
  1475. {
  1476.     _line = 0;            /* clear leaves us at top... */
  1477.     _col  = 0;
  1478.  
  1479.     if(ps_global->in_init_seq)
  1480.       return;
  1481.  
  1482.     mark_status_unknown();
  1483.     mark_keymenu_dirty();
  1484.     mark_titlebar_dirty();
  1485.  
  1486.     ibmmove(0, 0);
  1487.     ibmeeop();
  1488. }
  1489.  
  1490.  
  1491.  
  1492. /*----------------------------------------------------------------------
  1493.         Move the cursor to the row and column number
  1494.  Input:  row number
  1495.          column number
  1496.  
  1497.  Result: Cursor moves
  1498.          internal position updated
  1499.   ----------------------------------------------------------------------*/
  1500. void
  1501. MoveCursor(row, col)                /* DOS */
  1502.      int row, col;
  1503. {
  1504.     /** move cursor to the specified row column on the screen.
  1505.         0,0 is the top left! **/
  1506.  
  1507.     if(ps_global->in_init_seq)
  1508.       return;
  1509.  
  1510.     ibmmove(row, col);
  1511.     _line = row;
  1512.     _col = col;
  1513. }
  1514.  
  1515.  
  1516.  
  1517. /*----------------------------------------------------------------------
  1518.          Newline, move the cursor to the start of next line
  1519.  
  1520.  Input:  none
  1521.  
  1522.  Result: Cursor moves
  1523.   ----------------------------------------------------------------------*/
  1524. void
  1525. NewLine()                    /* DOS */
  1526. {
  1527.     /** move the cursor to the beginning of the next line **/
  1528.  
  1529.     MoveCursor(_line+1, 0);
  1530. }
  1531.  
  1532.  
  1533.  
  1534.  
  1535. /*----------------------------------------------------------------------
  1536.        Start painting inverse on the screen
  1537.  
  1538.  Input:  none
  1539.  
  1540.  Result: escape sequence to go into inverse is output
  1541.          returns 1 if it was done, 0 if not.
  1542.   ----------------------------------------------------------------------*/
  1543. int
  1544. StartInverse()                    /* DOS */
  1545. {
  1546.     if(_in_inverse)
  1547.       return(1);
  1548.  
  1549.     _in_inverse = 1;
  1550.     ibmrev(1);                    /* libpico call */
  1551.     return(1);
  1552. }
  1553.  
  1554.  
  1555. /*----------------------------------------------------------------------
  1556.       End painting inverse on the screen
  1557.  
  1558.  Input:  none
  1559.  
  1560.  Result: escape sequence to go out of inverse is output
  1561.          returns 1 if it was done, 0 if not.
  1562.   ----------------------------------------------------------------------*/
  1563. void
  1564. EndInverse()                    /* DOS */
  1565. {
  1566.     if(_in_inverse){
  1567.     _in_inverse = 0;
  1568.     ibmrev(0);                /* libpico call */
  1569.     }
  1570. }
  1571.  
  1572.  
  1573. /*
  1574.  * Character attriute stuff that could use some work
  1575.  * MS 92.05.18
  1576.  */
  1577.  
  1578. int
  1579. StartUnderline()                /* DOS */
  1580. {
  1581.     return(0);
  1582. }
  1583.  
  1584. void                        /* DOS */
  1585. EndUnderline()
  1586. {
  1587. }
  1588.  
  1589. int
  1590. StartBold()                    /* DOS */
  1591. {
  1592.     return(0);
  1593. }
  1594.  
  1595. void
  1596. EndBold()                    /* DOS */
  1597. {
  1598. }
  1599.  
  1600.  
  1601. /*----------------------------------------------------------------------
  1602.        Insert character on screen pushing others right
  1603.  
  1604.  Input:  character to output
  1605.          termcap escape sequences
  1606.  
  1607.  Result: charcter is inserted if possible
  1608.          return -1 if it can't be done
  1609.   ----------------------------------------------------------------------*/
  1610. InsertChar(c)                    /* DOS */
  1611.      int c;
  1612. {
  1613. #ifdef _WINDOWS
  1614.     mswin_inschar (c);
  1615.     return (0);
  1616. #else
  1617.     return(-1);
  1618. #endif
  1619. }
  1620.  
  1621.  
  1622. /*----------------------------------------------------------------------
  1623.          Delete n characters from line, sliding rest of line left
  1624.  
  1625.  Input:  number of characters to delete
  1626.          termcap escape sequences
  1627.  
  1628.  Result: characters deleted on screen
  1629.          returns -1 if it wasn't done
  1630.   ----------------------------------------------------------------------*/
  1631. DeleteChar(n)                    /* DOS */
  1632.      int n;
  1633. {
  1634.     char c;
  1635.     int oc;                /* original column */
  1636.  
  1637. #ifdef _WINDOWS
  1638.     mswin_delchar ();
  1639. #else
  1640.     oc = _col;
  1641. /* cursor OFF */
  1642.     while(_col < 79){
  1643.     ibmmove(_line, _col+1);
  1644.         readscrn(&c);
  1645.     ibmmove(_line, _col++);
  1646.     ibmputc(c);
  1647.     }
  1648.     ibmputc(' ');
  1649.     ibmmove(_line, oc);
  1650. /* cursor ON */
  1651. #endif
  1652. }
  1653.  
  1654.  
  1655.  
  1656. /*----------------------------------------------------------------------
  1657.   Go into scrolling mode, that is set scrolling region if applicable
  1658.  
  1659.  Input: top line of region to scroll
  1660.         bottom line of region to scroll
  1661.  
  1662.  Result: either set scrolling region or
  1663.          save values for later scrolling
  1664.          returns -1 if we can't scroll
  1665.  
  1666.  Unfortunately this seems to leave the cursor in an unpredictable place
  1667.  at least the manuals don't say were, so we force it here.
  1668. ----------------------------------------------------------------------*/
  1669. static int __t, __b;
  1670. BeginScroll(top, bottom)            /* DOS */
  1671.      int top, bottom;
  1672. {
  1673.     __t = top;
  1674.     __b = bottom;
  1675. }
  1676.  
  1677. /*----------------------------------------------------------------------
  1678.    End scrolling -- clear scrolling regions if necessary
  1679.  
  1680.  Input:  none
  1681.  
  1682.  Result: Clear scrolling region on terminal
  1683.   ----------------------------------------------------------------------*/
  1684. void
  1685. EndScroll()                    /* DOS */
  1686. {
  1687. }
  1688.  
  1689.  
  1690. /* ----------------------------------------------------------------------
  1691.     Scroll the screen using insert/delete or scrolling regions
  1692.  
  1693.  Input:  number of lines to scroll, positive forward
  1694.  
  1695.  Result: Screen scrolls
  1696.          returns 0 if scroll succesful, -1 if not
  1697.  
  1698.  positive lines goes foward (new lines come in at bottom
  1699.  Leaves cursor at the place to insert put new text
  1700.  
  1701.  0,0 is the upper left
  1702.  ----------------------------------------------------------------------*/
  1703. ScrollRegion(lines)                /* DOS */
  1704.     int lines;
  1705. {
  1706.     return(-1);
  1707. }
  1708.  
  1709.  
  1710. /*----------------------------------------------------------------------
  1711.     Write a character to the screen, keeping track of cursor position
  1712.  
  1713.  Input:  charater to write
  1714.  
  1715.  Result: character output
  1716.          cursor position variables updated
  1717.   ----------------------------------------------------------------------*/
  1718. Writechar(ch, new_esc_len)                /* DOS */
  1719.      register unsigned int ch;
  1720.      int      new_esc_len;
  1721. {
  1722.     register int nt;
  1723.  
  1724.     if(ps_global->in_init_seq)
  1725.       return(0);
  1726.  
  1727.     switch(ch){
  1728.       case LINE_FEED :
  1729.     _line = min(_line+1,ps_global->ttyo->screen_rows);
  1730.         _col =0;
  1731.         ibmmove(_line, _col);
  1732.     break;
  1733.  
  1734.       case RETURN :        /* move to column 0 */
  1735.     _col = 0;
  1736.         ibmmove(_line, _col);
  1737.  
  1738.       case BACKSPACE :        /* move back a space if not in column 0 */
  1739.     if(_col > 0)
  1740.           ibmmove(_line, --_col);
  1741.  
  1742.     break;
  1743.     
  1744.       case BELL :        /* ring the bell but don't advance _col */
  1745.     ibmbeep();        /* libpico call */
  1746.     break;
  1747.  
  1748.       case TAB:            /* if a tab, output it */
  1749.     do
  1750.       ibmputc(' ');
  1751.     while(((++_col)&0x07) != 0);
  1752.     break;
  1753.  
  1754.       default:
  1755.     /*if some kind of control or  non ascii character change to a '?'*/
  1756.     if(iscntrl(ch & 0x7f))
  1757.       ch = '?';
  1758.  
  1759.     ibmputc(ch);
  1760.     _col++;
  1761.     }
  1762.  
  1763.     if(_col == ps_global->ttyo->screen_cols) {
  1764.       _col  = 0;
  1765.       if(_line + 1 < ps_global->ttyo->screen_rows)
  1766.         _line++;
  1767.  
  1768.       ibmmove(_line, _col);
  1769.     }
  1770.  
  1771.     return(0);
  1772. }
  1773.  
  1774.  
  1775. /*----------------------------------------------------------------------
  1776.       Printf style write directly to the terminal at current position
  1777.  
  1778.  Input: printf style control string
  1779.         number of printf style arguments
  1780.         up to three printf style arguments
  1781.  
  1782.  Result: Line written to the screen
  1783.   ----------------------------------------------------------------------*/
  1784. void
  1785. Write_to_screen(string)                /* DOS */
  1786.       register char *string;
  1787. {
  1788.     if(ps_global->in_init_seq)
  1789.       return;
  1790.  
  1791. #ifdef _WINDOWS
  1792.     mswin_puts (string);
  1793. #else
  1794.     while(*string)
  1795.       Writechar(*string++, 0);
  1796. #endif
  1797. }
  1798.  
  1799.  
  1800.  
  1801. /*----------------------------------------------------------------------
  1802.     Clear screen to end of line on current line
  1803.  
  1804.  Input:  none
  1805.  
  1806.  Result: Line is cleared
  1807.   ----------------------------------------------------------------------*/
  1808. void
  1809. CleartoEOLN()                    /* DOS */
  1810. {
  1811.     ibmeeol();                    /* libpico call */
  1812. }
  1813.  
  1814.  
  1815. /*----------------------------------------------------------------------
  1816.           Clear screen to end of screen from current point
  1817.  
  1818.  Input: none
  1819.  
  1820.  Result: screen is cleared
  1821.   ----------------------------------------------------------------------*/
  1822. CleartoEOS()                    /* DOS */
  1823. {
  1824.     ibmeeop();
  1825. }
  1826.  
  1827.  
  1828. /*----------------------------------------------------------------------
  1829.      function to output string such that it becomes icon text
  1830.  
  1831.    Args: s -- string to write
  1832.  
  1833.  Result: string indicated become our "icon" text
  1834.   ----*/
  1835. void
  1836. icon_text(s)                    /* DOS */
  1837.     char *s;
  1838. {
  1839. #ifdef _WINDOWS
  1840.     mswin_newmailtext ((s) ? s : ps_global->pine_name);
  1841. #endif
  1842.     return;                    /* NO OP */
  1843. }
  1844.  
  1845.  
  1846. #ifndef    _WINDOWS
  1847. /*
  1848.  * readscrn - DOS magic to read the character on the display at the
  1849.  *            current cursor position
  1850.  */
  1851. readscrn(c)                    /* DOS */
  1852. char *c;
  1853. {
  1854.     ibmgetc(c);
  1855. }
  1856. #endif    /* !_WINDOWS */
  1857. #endif    /* DOS -- End of giant ifdef for DOS drivers */
  1858.  
  1859.  
  1860. /*
  1861.  * Generic tty output routines...
  1862.  */
  1863.  
  1864. /*----------------------------------------------------------------------
  1865.       Printf style output line to the screen at given position, 0 args
  1866.  
  1867.   Args:  x -- column position on the screen
  1868.          y -- row position on the screen
  1869.          line -- line of text to output
  1870.  
  1871.  Result: text is output
  1872.          cursor position is update
  1873.   ----*/
  1874. void
  1875. PutLine0(x, y, line)
  1876.     int            x,y;
  1877.     register char *line;
  1878. {
  1879.     MoveCursor(x,y);
  1880.     Write_to_screen(line);
  1881. }
  1882.  
  1883.  
  1884.  
  1885. /*----------------------------------------------------------------------
  1886.   Output line of length len to the display observing embedded attributes
  1887.  
  1888.  Args:  x      -- column position on the screen
  1889.         y      -- column position on the screen
  1890.         line   -- text to be output
  1891.         length -- length of text to be output
  1892.  
  1893.  Result: text is output
  1894.          cursor position is updated
  1895.   ----------------------------------------------------------------------*/
  1896. void
  1897. PutLine0n8b(x, y, line, length)
  1898.     int            x, y, length;
  1899.     register char *line;
  1900. {
  1901.     unsigned char c;
  1902.  
  1903.     MoveCursor(x,y);
  1904.     while(length-- && (c = (unsigned char)*line++))
  1905.       if(c == (unsigned char)TAG_EMBED && length){
  1906.       length--;
  1907.       switch(*line++){
  1908.         case TAG_INVON :
  1909.           StartInverse();
  1910.           break;
  1911.         case TAG_INVOFF :
  1912.           EndInverse();
  1913.           break;
  1914.         case TAG_BOLDON :
  1915.           StartBold();
  1916.           break;
  1917.         case TAG_BOLDOFF :
  1918.           EndBold();
  1919.           break;
  1920.         case TAG_ULINEON :
  1921.           StartUnderline();
  1922.           break;
  1923.         case TAG_ULINEOFF :
  1924.           EndUnderline();
  1925.           break;
  1926.         /* default: other embedded vals are handles, just ignore 'em */
  1927.       }                    /* tag with handle, skip it */
  1928.       }    
  1929.       else if(c == '\033')            /* check for iso-2022 escape */
  1930.     Writechar(c, match_escapes(line));
  1931.       else
  1932.     Writechar(c, 0);
  1933. }
  1934.  
  1935.  
  1936. /*----------------------------------------------------------------------
  1937.       Printf style output line to the screen at given position, 1 arg
  1938.  
  1939.  Input:  position on the screen
  1940.          line of text to output
  1941.  
  1942.  Result: text is output
  1943.          cursor position is update
  1944.   ----------------------------------------------------------------------*/
  1945. void
  1946. /*VARARGS2*/
  1947. PutLine1(x, y, line, arg1)
  1948.     int   x, y;
  1949.     char *line;
  1950.     void *arg1;
  1951. {
  1952.     char buffer[PUTLINE_BUFLEN];
  1953.  
  1954.     sprintf(buffer, line, arg1);
  1955.     PutLine0(x, y, buffer);
  1956. }
  1957.  
  1958.  
  1959. /*----------------------------------------------------------------------
  1960.       Printf style output line to the screen at given position, 2 args
  1961.  
  1962.  Input:  position on the screen
  1963.          line of text to output
  1964.  
  1965.  Result: text is output
  1966.          cursor position is update
  1967.   ----------------------------------------------------------------------*/
  1968. void
  1969. /*VARARGS3*/
  1970. PutLine2(x, y, line, arg1, arg2)
  1971.     int   x, y;
  1972.     char *line;
  1973.     void *arg1, *arg2;
  1974. {
  1975.     char buffer[PUTLINE_BUFLEN];
  1976.  
  1977.     sprintf(buffer, line, arg1, arg2);
  1978.     PutLine0(x, y, buffer);
  1979. }
  1980.  
  1981.  
  1982. /*----------------------------------------------------------------------
  1983.       Printf style output line to the screen at given position, 3 args
  1984.  
  1985.  Input:  position on the screen
  1986.          line of text to output
  1987.  
  1988.  Result: text is output
  1989.          cursor position is update
  1990.   ----------------------------------------------------------------------*/
  1991. void
  1992. /*VARARGS4*/
  1993. PutLine3(x, y, line, arg1, arg2, arg3)
  1994.     int   x, y;
  1995.     char *line;
  1996.     void *arg1, *arg2, *arg3;
  1997. {
  1998.     char buffer[PUTLINE_BUFLEN];
  1999.  
  2000.     sprintf(buffer, line, arg1, arg2, arg3);
  2001.     PutLine0(x, y, buffer);
  2002. }
  2003.  
  2004.  
  2005. /*----------------------------------------------------------------------
  2006.       Printf style output line to the screen at given position, 4 args
  2007.  
  2008.  Args:  x -- column position on the screen
  2009.         y -- column position on the screen
  2010.         line -- printf style line of text to output
  2011.  
  2012.  Result: text is output
  2013.          cursor position is update
  2014.   ----------------------------------------------------------------------*/
  2015. void
  2016. /*VARARGS5*/
  2017. PutLine4(x, y, line, arg1, arg2, arg3, arg4)
  2018.      int   x, y;
  2019.      char *line;
  2020.      void *arg1, *arg2, *arg3, *arg4;
  2021. {
  2022.     char buffer[PUTLINE_BUFLEN];
  2023.  
  2024.     sprintf(buffer, line, arg1, arg2, arg3, arg4);
  2025.     PutLine0(x, y, buffer);
  2026. }
  2027.  
  2028.  
  2029.  
  2030. /*----------------------------------------------------------------------
  2031.       Printf style output line to the screen at given position, 5 args
  2032.  
  2033.  Args:  x -- column position on the screen
  2034.         y -- column position on the screen
  2035.         line -- printf style line of text to output
  2036.  
  2037.  Result: text is output
  2038.          cursor position is update
  2039.   ----------------------------------------------------------------------*/
  2040. void
  2041. /*VARARGS6*/
  2042. PutLine5(x, y, line, arg1, arg2, arg3, arg4, arg5)
  2043.      int   x, y;
  2044.      char *line;
  2045.      void *arg1, *arg2, *arg3, *arg4, *arg5;
  2046. {
  2047.     char buffer[PUTLINE_BUFLEN];
  2048.  
  2049.     sprintf(buffer, line, arg1, arg2, arg3, arg4, arg5);
  2050.     PutLine0(x, y, buffer);
  2051. }
  2052.  
  2053.  
  2054.  
  2055. /*----------------------------------------------------------------------
  2056.        Output a line to the screen, centered
  2057.  
  2058.   Input:  Line number to print on, string to output
  2059.   
  2060.  Result:  String is output to screen
  2061.           Returns column number line is output on
  2062.   ----------------------------------------------------------------------*/
  2063. int
  2064. Centerline(line, string)
  2065.     int   line;
  2066.     char *string;
  2067. {
  2068.     register int length, col;
  2069.  
  2070.     length = strlen(string);
  2071.  
  2072.     if (length > ps_global->ttyo->screen_cols)
  2073.       col = 0;
  2074.     else
  2075.       col = (ps_global->ttyo->screen_cols - length) / 2;
  2076.  
  2077.     PutLine0(line, col, string);
  2078.     return(col);
  2079. }
  2080.  
  2081.  
  2082.  
  2083. /*----------------------------------------------------------------------
  2084.      Clear specified line on the screen
  2085.  
  2086.  Result: The line is blanked and the cursor is left at column 0.
  2087.  
  2088.   ----*/
  2089. void
  2090. ClearLine(n)
  2091.     int n;
  2092. {
  2093.     if(ps_global->in_init_seq)
  2094.       return;
  2095.  
  2096.     MoveCursor(n, 0);
  2097.     CleartoEOLN();
  2098. }
  2099.  
  2100.  
  2101.  
  2102. /*----------------------------------------------------------------------
  2103.      Clear specified lines on the screen
  2104.  
  2105.  Result: The lines starting at 'x' and ending at 'y' are blanked
  2106.      and the cursor is left at row 'x', column 0
  2107.  
  2108.   ----*/
  2109. void
  2110. ClearLines(x, y)
  2111.     int x, y;
  2112. {
  2113.     int i;
  2114.  
  2115.     for(i = x; i <= y; i++)
  2116.       ClearLine(i);
  2117.  
  2118.     MoveCursor(x, 0);
  2119. }
  2120.  
  2121.  
  2122.  
  2123. /*----------------------------------------------------------------------
  2124.     Indicate to the screen painting here that the position of the cursor
  2125.  has been disturbed and isn't where these functions might think.
  2126.  ----*/
  2127. void
  2128. clear_cursor_pos()
  2129. {
  2130.     _line = FARAWAY;
  2131.     _col  = FARAWAY;
  2132. }
  2133.  
  2134.  
  2135. /*----------------------------------------------------------------------
  2136.       Return current inverse state
  2137.  
  2138.  Result: returns 1 if in inverse state, 0 if not.
  2139.   ----------------------------------------------------------------------*/
  2140. int
  2141. InverseState()
  2142. {
  2143.     return(_in_inverse);
  2144. }
  2145.